package com.codefalse.mybatis.gen.plugin;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;

import java.util.List;

/**
 * @author songxiangfeng
 * Created At 2021-02-18 16:20
 */
public class ModelColumnPlugin extends PluginAdapter {
    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        FullyQualifiedJavaType stringJavaType = new FullyQualifiedJavaType("String");

        InnerEnum columnEnum = new InnerEnum("Column");
        columnEnum.setVisibility(JavaVisibility.PUBLIC);
        //构造方法
        Method constructorMethod = new Method("Column");
        constructorMethod.setConstructor(true);
        constructorMethod.addParameter(new Parameter(new FullyQualifiedJavaType("String"), "actualName"));
        constructorMethod.addBodyLine("this.actualName = actualName;");
        columnEnum.addMethod(constructorMethod);
        //表中字段
        Field columnField = new Field("actualName", new FullyQualifiedJavaType("String"));
        columnField.setFinal(true);
        columnField.setVisibility(JavaVisibility.PRIVATE);
        columnEnum.addField(columnField);

        Method verifyTableAliasMethod = new Method("verifyTableAlias");
        verifyTableAliasMethod.setVisibility(JavaVisibility.PRIVATE);
        verifyTableAliasMethod.setReturnType(stringJavaType);
        verifyTableAliasMethod.addParameter(new Parameter(stringJavaType, "tableAlias"));
        verifyTableAliasMethod.addBodyLine("if (null == tableAlias || \"\".equals(tableAlias)) {");
        verifyTableAliasMethod.addBodyLine("return \"`\" + this.actualName + \"`\";");
        verifyTableAliasMethod.addBodyLine("}");
        verifyTableAliasMethod.addBodyLine("return \"`\" + tableAlias + \".\" + this.actualName + \"`\";");
        columnEnum.addMethod(verifyTableAliasMethod);


        //get方法
        Method getColumnMethod1 = new Method("getActualName");
        getColumnMethod1.setVisibility(JavaVisibility.PUBLIC);
        getColumnMethod1.setReturnType(stringJavaType);
        getColumnMethod1.addBodyLine("return getActualName(null);");
        columnEnum.addMethod(getColumnMethod1);
        Method getColumnMethod = new Method("getActualName");
        getColumnMethod.setVisibility(JavaVisibility.PUBLIC);
        getColumnMethod.setReturnType(stringJavaType);
        getColumnMethod.addParameter(new Parameter(stringJavaType, "tableAlias"));
        getColumnMethod.addBodyLine("return verifyTableAlias(tableAlias);");
        columnEnum.addMethod(getColumnMethod);

        //asc
        Method ascMethod = new Method("asc");
        ascMethod.setVisibility(JavaVisibility.PUBLIC);
        ascMethod.setReturnType(stringJavaType);
        ascMethod.addParameter(new Parameter(stringJavaType, "tableAlias"));
        ascMethod.addBodyLine("return verifyTableAlias(tableAlias)+ \" ASC\";");
        columnEnum.addMethod(ascMethod);
        Method asc1Method = new Method("asc");
        asc1Method.setVisibility(JavaVisibility.PUBLIC);
        asc1Method.setReturnType(stringJavaType);
        asc1Method.addBodyLine("return asc(null);");
        columnEnum.addMethod(asc1Method);
        //desc
        Method desc1Method = new Method("desc");
        desc1Method.setVisibility(JavaVisibility.PUBLIC);
        desc1Method.setReturnType(stringJavaType);
        desc1Method.addBodyLine("return desc(null);");
        columnEnum.addMethod(desc1Method);
        Method descMethod = new Method("desc");
        descMethod.setVisibility(JavaVisibility.PUBLIC);
        descMethod.setReturnType(stringJavaType);
        descMethod.addParameter(new Parameter(stringJavaType, "tableAlias"));
        descMethod.addBodyLine("return verifyTableAlias(tableAlias)+ \" DESC\";");
        columnEnum.addMethod(descMethod);

        //获取全表字段
        List<IntrospectedColumn> primaryKeyColumns = introspectedTable.getPrimaryKeyColumns();
        for (IntrospectedColumn column : primaryKeyColumns) {
            String constant = column.getJavaProperty() + "(\""+column.getActualColumnName()+"\")";
            columnEnum.addEnumConstant(constant);
        }
        List<IntrospectedColumn> introspectedColumns = introspectedTable.getBaseColumns();
        for (IntrospectedColumn column : introspectedColumns) {
            String constant = column.getJavaProperty() + "(\""+column.getActualColumnName()+"\")";
            columnEnum.addEnumConstant(constant);
        }

        topLevelClass.addInnerEnum(columnEnum);
        return true;
    }
}
